<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
    />
    <meta
      name="description"
      content="Apply elevation band material to the globe."
    />
    <meta name="cesium-sandcastle-labels" content="Showcases" />
    <title>Cesium Demo</title>
    <script type="text/javascript" src="../Sandcastle-header.js"></script>
    <script
      type="text/javascript"
      src="../../../Build/CesiumUnminified/Cesium.js"
      nomodule
    ></script>
    <script type="module" src="../load-cesium-es6.js"></script>
  </head>
  <body
    class="sandcastle-loading"
    data-sandcastle-bucket="bucket-requirejs.html"
  >
    <style>
      @import url(../templates/bucket.css);
    </style>
    <div id="cesiumContainer" class="fullSize"></div>
    <div id="loadingOverlay"><h1>Loading...</h1></div>
    <div id="toolbar">
      <table>
        <tbody>
          <tr>
            <td>Background Transparency</td>
            <td>
              <input
                type="range"
                min="0.0"
                max="1.0"
                step="0.01"
                data-bind="value: backgroundTransparency, valueUpdate: 'input'"
              />
            </td>
          </tr>
          <tr>
            <td>Band Transparency</td>
            <td>
              <input
                type="range"
                min="0.0"
                max="1.0"
                step="0.01"
                data-bind="value: bandTransparency, valueUpdate: 'input'"
              />
            </td>
          </tr>
          <tr>
            <td>Band Thickness</td>
            <td>
              <input
                type="range"
                min="10"
                max="1000"
                step="1"
                data-bind="value: bandThickness, valueUpdate: 'input'"
              />
            </td>
          </tr>
          <tr>
            <td>Band 1 Position</td>
            <td>
              <input
                type="range"
                min="4000"
                max="8848"
                step="1"
                data-bind="value: band1Position, valueUpdate: 'input'"
              />
            </td>
          </tr>
          <tr>
            <td>Band 2 Position</td>
            <td>
              <input
                type="range"
                min="4000"
                max="8848"
                step="1"
                data-bind="value: band2Position, valueUpdate: 'input'"
              />
            </td>
          </tr>
          <tr>
            <td>Band 3 Position</td>
            <td>
              <input
                type="range"
                min="4000"
                max="8848"
                step="1"
                data-bind="value: band3Position, valueUpdate: 'input'"
              />
            </td>
          </tr>
          <tr>
            <td>Gradient</td>
            <td>
              <input type="checkbox" data-bind="checked: gradient" />
            </td>
          </tr>
        </tbody>
      </table>
    </div>
    <script id="cesium_sandcastle_script">
      function startup(Cesium) {
        "use strict";
        //Sandcastle_Begin
        const viewer = new Cesium.Viewer("cesiumContainer", {
          terrainProvider: Cesium.createWorldTerrain({
            requestVertexNormals: true, //Needed to visualize slope
          }),
        });

        viewer.camera.setView({
          destination: new Cesium.Cartesian3(
            290637.5534733206,
            5637471.593707632,
            2978256.8126927214
          ),
          orientation: {
            heading: 4.747266966349747,
            pitch: -0.2206998858596192,
            roll: 6.280340554587955,
          },
        });

        const viewModel = {
          gradient: false,
          band1Position: 7000.0,
          band2Position: 7500.0,
          band3Position: 8000.0,
          bandThickness: 100.0,
          bandTransparency: 0.5,
          backgroundTransparency: 0.75,
        };

        Cesium.knockout.track(viewModel);
        const toolbar = document.getElementById("toolbar");
        Cesium.knockout.applyBindings(viewModel, toolbar);
        for (const name in viewModel) {
          if (viewModel.hasOwnProperty(name)) {
            Cesium.knockout
              .getObservable(viewModel, name)
              .subscribe(updateMaterial);
          }
        }

        function updateMaterial() {
          const gradient = Boolean(viewModel.gradient);
          const band1Position = Number(viewModel.band1Position);
          const band2Position = Number(viewModel.band2Position);
          const band3Position = Number(viewModel.band3Position);
          const bandThickness = Number(viewModel.bandThickness);
          const bandTransparency = Number(viewModel.bandTransparency);
          const backgroundTransparency = Number(
            viewModel.backgroundTransparency
          );

          const layers = [];
          const backgroundLayer = {
            entries: [
              {
                height: 4200.0,
                color: new Cesium.Color(0.0, 0.0, 0.2, backgroundTransparency),
              },
              {
                height: 8000.0,
                color: new Cesium.Color(1.0, 1.0, 1.0, backgroundTransparency),
              },
              {
                height: 8500.0,
                color: new Cesium.Color(1.0, 0.0, 0.0, backgroundTransparency),
              },
            ],
            extendDownwards: true,
            extendUpwards: true,
          };
          layers.push(backgroundLayer);

          const gridStartHeight = 4200.0;
          const gridEndHeight = 8848.0;
          const gridCount = 50;
          for (let i = 0; i < gridCount; i++) {
            const lerper = i / (gridCount - 1);
            const heightBelow = Cesium.Math.lerp(
              gridStartHeight,
              gridEndHeight,
              lerper
            );
            const heightAbove = heightBelow + 10.0;
            const alpha =
              Cesium.Math.lerp(0.2, 0.4, lerper) * backgroundTransparency;
            layers.push({
              entries: [
                {
                  height: heightBelow,
                  color: new Cesium.Color(1.0, 1.0, 1.0, alpha),
                },
                {
                  height: heightAbove,
                  color: new Cesium.Color(1.0, 1.0, 1.0, alpha),
                },
              ],
            });
          }

          const antialias = Math.min(10.0, bandThickness * 0.1);

          if (!gradient) {
            const band1 = {
              entries: [
                {
                  height: band1Position - bandThickness * 0.5 - antialias,
                  color: new Cesium.Color(0.0, 0.0, 1.0, 0.0),
                },
                {
                  height: band1Position - bandThickness * 0.5,
                  color: new Cesium.Color(0.0, 0.0, 1.0, bandTransparency),
                },
                {
                  height: band1Position + bandThickness * 0.5,
                  color: new Cesium.Color(0.0, 0.0, 1.0, bandTransparency),
                },
                {
                  height: band1Position + bandThickness * 0.5 + antialias,
                  color: new Cesium.Color(0.0, 0.0, 1.0, 0.0),
                },
              ],
            };

            const band2 = {
              entries: [
                {
                  height: band2Position - bandThickness * 0.5 - antialias,
                  color: new Cesium.Color(0.0, 1.0, 0.0, 0.0),
                },
                {
                  height: band2Position - bandThickness * 0.5,
                  color: new Cesium.Color(0.0, 1.0, 0.0, bandTransparency),
                },
                {
                  height: band2Position + bandThickness * 0.5,
                  color: new Cesium.Color(0.0, 1.0, 0.0, bandTransparency),
                },
                {
                  height: band2Position + bandThickness * 0.5 + antialias,
                  color: new Cesium.Color(0.0, 1.0, 0.0, 0.0),
                },
              ],
            };

            const band3 = {
              entries: [
                {
                  height: band3Position - bandThickness * 0.5 - antialias,
                  color: new Cesium.Color(1.0, 0.0, 0.0, 0.0),
                },
                {
                  height: band3Position - bandThickness * 0.5,
                  color: new Cesium.Color(1.0, 0.0, 0.0, bandTransparency),
                },
                {
                  height: band3Position + bandThickness * 0.5,
                  color: new Cesium.Color(1.0, 0.0, 0.0, bandTransparency),
                },
                {
                  height: band3Position + bandThickness * 0.5 + antialias,
                  color: new Cesium.Color(1.0, 0.0, 0.0, 0.0),
                },
              ],
            };

            layers.push(band1);
            layers.push(band2);
            layers.push(band3);
          } else {
            const combinedBand = {
              entries: [
                {
                  height: band1Position - bandThickness * 0.5,
                  color: new Cesium.Color(0.0, 0.0, 1.0, bandTransparency),
                },
                {
                  height: band2Position,
                  color: new Cesium.Color(0.0, 1.0, 0.0, bandTransparency),
                },
                {
                  height: band3Position + bandThickness * 0.5,
                  color: new Cesium.Color(1.0, 0.0, 0.0, bandTransparency),
                },
              ],
            };

            layers.push(combinedBand);
          }

          const material = Cesium.createElevationBandMaterial({
            scene: viewer.scene,
            layers: layers,
          });
          viewer.scene.globe.material = material;
        }

        updateMaterial();
        //Sandcastle_End
        Sandcastle.finishedLoading();
      }
      if (typeof Cesium !== "undefined") {
        window.startupCalled = true;
        startup(Cesium);
      }
    </script>
  </body>
</html>
